#include "stdafx.h"
#include "Synchronizer.h"
#include "../Core/Random.h"
#include "../Core/TimeSpan.h"

#ifdef erase
#undef erase
#endif

namespace Core
{

	Synchronizer::Synchronizer() : m_Socket(Socket(Protocol_Udp))
	{
		SetAsStandby();
	}

	void Synchronizer::ExecuteByInterval()
	{
		m_RawData.Reset();
		while(!m_Socket.IsReceiverEmpty())
		{
			try
			{
				InternetAddress t_InternetAddress;
				m_Socket.ReceiveFrom(m_RawData, t_InternetAddress);
				unsigned long t_TimeStamp = m_RawData.ReadLong();
				if(t_TimeStamp==0)
				{
					SetAsStandby();
				}
				else
				{
					m_Times.erase(t_TimeStamp);
					m_Times.insert(std::pair<unsigned long, DateTime>(t_TimeStamp, DateTime()));
				}
			}
			catch(...)
			{
			}
		}
		std::vector<unsigned long> t_ToBeDeleted;
		DateTime t_Now;
		for(std::map<unsigned long, DateTime>::iterator p=m_Times.begin(); p!=m_Times.end(); p++)
		{
			if(t_Now.Delta(p->second)>5) t_ToBeDeleted.push_back(p->first);
		}
		for(std::vector<unsigned long>::iterator p=t_ToBeDeleted.begin(); p!=t_ToBeDeleted.end(); p++)
		{
			m_Times.erase(*p);
		}
		m_RawData.Reset();
		m_RawData.WriteLong(m_TimeStamp);
		m_Socket.Socket::SendTo(m_RawData, m_BroadcastAddress);
	}

	void Synchronizer::Start(unsigned short p_Port)
	{
		m_Socket.Bind(InternetAddress("", p_Port));
		m_Socket.StartReceiver();
		m_BroadcastAddress.Address = "255.255.255.255";
		m_BroadcastAddress.PortNumber = p_Port;
	}

	bool Synchronizer::IsPrimary()
	{
		return (GetLevel()==1);
	}

	unsigned char Synchronizer::GetLevel()
	{
		unsigned char t_Level = 1;
		for(std::map<unsigned long, DateTime>::iterator p=m_Times.begin(); p!=m_Times.end(); p++, t_Level++)
		{
			if(p->first==m_TimeStamp) break;
		}
		return t_Level;
	}

	void Synchronizer::SetAsStandby()
	{
		TimeSpan t_TimeSpan;
		m_TimeStamp = t_TimeSpan.GetSecond();
		m_TimeStamp %= 1000000;
		m_TimeStamp *= 1000;
		m_TimeStamp += t_TimeSpan.GetMilliSecond();
	}
}
